home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / System / PUCCNets Folder / CopyINIT.c next >
Encoding:
C/C++ Source or Header  |  1992-09-23  |  8.1 KB  |  327 lines  |  [TEXT/KAHL]

  1. /*
  2.  * CopyINIT - an INIT which prevents the copying of resource forks
  3.  * to or from the boot disk by the Finder by intercepting the PBOpenRF
  4.  * trap.
  5.  * It is intended for installation on the hard disks of Macs in public
  6.  * labs.
  7.  * Created and placed in the public domain by Dale Talcott,
  8.  * Purdue University Computing Center, 1989
  9.  */
  10.  
  11. #include <string.h>
  12.  
  13. #ifndef    NULL
  14. #define    NULL            0
  15. #endif
  16. #define    OUR_ERROR        vLckdErr    /* error when we reject operation */
  17. #define    OUR_ID            6500        /* id for resources */
  18. #define    OUR_TRAP_NO        0xa            /* PBOpenRF trap number */
  19.  
  20. #define    ZERO(s)        memset ((char *)&(s), 0, sizeof (s))    /* zero struct */
  21.  
  22. /*
  23.  *=========================================================================
  24.  * Globals
  25.  *=========================================================================
  26.  */
  27. int            BootVRefNum;            /* vRefNum of boot drive */
  28. long        Orig_trap;                /* original trap handler address */
  29. Handle        Our_DITL_hdl;            /* handle to DITL */
  30. Rect        Our_rect;                /* dialog window rectangle */
  31.  
  32.  
  33. /*
  34.  *=========================================================================
  35.  * Prototypes
  36.  *=========================================================================
  37.  */
  38. extern OSErr checkFile(HParmBlkPtr, Ptr);
  39. extern OSErr gripe(void);
  40. extern void main(Handle, long);
  41. extern void trap(void);
  42.  
  43.  
  44.  
  45. /*
  46.  *======================================================================
  47.  * trap() - the code which is given control on a PBOpenRF trap.
  48.  *        entry:        at first byte by INIT 31, a0 = handle to selves.
  49.  *                    at @1 from trap dispatcher
  50.  *        returns:    nothing if INIT 31,
  51.  *                    else for trap:
  52.  *                        OSErr if open not permitted, else
  53.  *                        exits via original PBOpenRF routine
  54.  *======================================================================
  55.  */
  56. void
  57. trap()
  58. {
  59.     asm {
  60. /*
  61.  *    Start of INIT code
  62.  */
  63. @0:
  64.      move.l        a4,-(sp)            /* save a4 */
  65.     lea            @0,a4                /* set up global ptr */
  66.     pea            @1                    /* set trap addr as second arg */
  67.     move.l        a0,-(sp)            /* put handle as first arg */
  68.     jsr            main
  69.     addq        #8,sp                /* discard args */
  70.     move.l        (sp)+,a4            /* restore a4 */
  71.     rts
  72.  
  73. /*
  74.  *    Start of trap code
  75.  */
  76. @1:
  77.     move.l        a6,-(sp)            /* fake link, part 1 (for debugger) */
  78.     movem.l        d0-d7/a0-a6,-(sp)    /* save regs */
  79.     lea            15*4(a7),a6            /* second half of link */
  80.     lea            trap,a4                /* set up global ptr */
  81. /*
  82.  *    Check whether to object or to pass to original trap handler.
  83.  *    We object if:
  84.  *        The current application is "Finder"
  85.  *        and the call is not from ROM and
  86.  *        CurrentA5 indicates an application is active
  87.  */
  88.     move.l        CurApName,d1        /* Check for Finder */
  89.     cmpi.l        #'\006Fin',d1
  90.     bne.s        @60
  91.     move.l        CurApName+4,d1
  92.     clr.b        d1
  93.     cmpi.l        #'der\000',d1
  94.     bne.s        @60
  95.  
  96.     move.l        4(a6),d1            /* our return address */
  97.     moveq        #8*4,d2                /* stack offset for trapper addr */
  98.     cmp.l        ROMBase,d1            /* check if called from ROM dispatch*/
  99.     bge.s        @3                    /* if so, trapper addr okay */
  100.     addq        #4,d2                /* MultiFinder adds extra layer */
  101. @3:
  102.     move.l        0(a6,d2.w),d2        /* fetch trapper return addr */
  103.     cmp.l        ROMBase,d2
  104.     bge.s        @60                    /* if called from ROM, okay */
  105.     
  106.     movea.l        CurrentA5,a2        /* Check for application */
  107.     cmpa.l        #0,a2
  108.     beq.s        @60
  109.     move.l        (a2),d1
  110.     beq.s        @60
  111. /*
  112.  *    Probably will object, let checkFile be the final arbiter
  113.  */
  114.     move.l        d1,-(sp)            /* arg2 = caller addr */
  115.     move.l        a0,-(sp)            /* arg1 = caller arg = PB addr */
  116.     jsr            checkFile
  117.     addq        #8,sp
  118.  
  119. /*
  120.  *    If checkFile returns 0, the call is okay,
  121.  *    otherwise we should pass the return value back to the caller
  122.  */
  123.     ext.l        d0
  124.     beq.s        @60
  125.     addq        #4,sp                /* discard original d0 */
  126.     movem.l        (sp)+,d1-d7/a0-a6
  127.     addq        #4,sp                /* discard link word */
  128.     rts                                /* exit to caller (via dispatcher) */
  129.  
  130. /*
  131.  *    Here to pass call on to original trap handler
  132.  */
  133. @60:
  134.     move.l        Orig_trap,(a6)        /* replace link word with trap addr */
  135.     movem.l        (sp)+,d0-d7/a0-a6
  136.     rts                                /* branch to handler */
  137.     }
  138.     /*NOTREACHED*/
  139. }
  140.  
  141.  
  142. /*
  143.  *=========================================================================
  144.  * checkFile(p,a) - see if we should object to file whose resource fork
  145.  *        is being opened
  146.  *    entry:    p = pointer to paramblock
  147.  *            a = caller return address
  148.  *    exit:    returns 0 if file okay.
  149.  *            returns <>0 if file not okay or on OS error
  150.  *=========================================================================
  151.  */
  152. OSErr
  153. checkFile (PBp, addr)
  154.     register HParmBlkPtr PBp;
  155.     Ptr                addr;
  156. {
  157.     HParamBlockRec    ourPB;            /* local copy of paramblock */
  158.     OSErr            error;
  159.     register long    ftype;
  160.     register long    fcreator;
  161.  
  162.     /*
  163.      * See if file is on boot drive.  If not, let it go.
  164.      */
  165.     if (PBp->ioParam.ioVRefNum != BootVRefNum)
  166.         return 0;
  167.     /*
  168.      * Look up info about the file.
  169.      */
  170.     ourPB = *PBp;
  171.     ourPB.fileParam.ioCompletion = 0;
  172.     ourPB.fileParam.ioFDirIndex = 0;
  173.     error = PBHGetFInfo (&ourPB, FALSE);
  174.     if (error) {
  175.         if (error == fnfErr)
  176.             error = 0;
  177.         return error;
  178.     }
  179.     /*
  180.      * Check for allowed file types.  These can always be opened.
  181.      */
  182.     ftype     = ourPB.fileParam.ioFlFndrInfo.fdType;
  183.     fcreator = ourPB.fileParam.ioFlFndrInfo.fdCreator;
  184.     if (ftype == 'TEXT'
  185.     ||  ftype == 'PICT'
  186.     )
  187.         return 0;
  188.     /*
  189.      * Check for disallowed types or creators.  These are the ones
  190.      * we are worried about.
  191.      */
  192.     if (ftype != 'APPL'
  193.     &&    ftype != 'INIT'
  194.     &&    ftype != 'ZSYS'
  195.     &&    ftype != 'cdev'
  196.     &&    fcreator != 'MACS'
  197.     )
  198.         return 0;
  199.     return (gripe());
  200. }
  201.  
  202.  
  203. /*
  204.  *=========================================================================
  205.  * gripe() - Display modal dialog warning that copying not permitted
  206.  *=========================================================================
  207.  */
  208. OSErr
  209. gripe()
  210. {
  211.     Handle            ditlh;            /* handle to DITL */
  212.     register DialogPtr dp;
  213.     OSErr            error;
  214.     register Handle    h;                /* temp handle */
  215.     short            itemHit;        /* for dialogs */
  216.     Str255            title;
  217.  
  218.     /*
  219.      * make a copy of our DITL (because DisposDialog() frees it)
  220.      * then build a dialog from it and let ModalDialog handle it
  221.      * thereafter.
  222.      */
  223.     title[0] = 0;
  224.     itemHit = 0;
  225.     ditlh = Our_DITL_hdl;
  226.     if ((error = HandToHand(&ditlh)) == 0) {
  227.         dp = NewDialog (
  228.             (DialogPeek)NULL,            /* storage */
  229.             &Our_rect,                    /* bounds rect */
  230.             title,                        /* title */
  231.             TRUE,                        /* visible */
  232.             dBoxProc,                    /* window type */
  233.             (WindowPtr)-1,                /* behind window */
  234.             FALSE,                        /* goaway box */
  235.             0l,                            /* refCon */
  236.             ditlh);                        /* item list */
  237.  
  238.         if (dp) {
  239.             while (itemHit != 1) {
  240.                 ModalDialog ((ProcPtr) NULL, &itemHit);
  241.             }
  242.             DisposDialog (dp);
  243.         }
  244.     }
  245.     if (error == 0 && (error = MemError ()) == 0)
  246.         error = OUR_ERROR;
  247.     return (error);
  248. }
  249.  
  250.  
  251. /*
  252.  *=========================================================================
  253.  * main - the code executed during startup
  254.  *=========================================================================
  255.  */
  256. void
  257. main(self, addr)
  258.     Handle    self;
  259.     long    addr;
  260. {
  261.     register Handle h;                /* general temp handle */
  262.     long            len;            /* length of trap code */
  263.     register Ptr    p;                /* general temp pointer */
  264.     WDPBRec            pb;                /* for getting boot vRefNum */
  265.  
  266.     HLock (self);
  267.     /*
  268.      * Check environment.  Exit silently if not kosher.
  269.      */
  270.     if (FSFCBLen == -1)            /* must have HFS */
  271.         goto exit;
  272.     /*
  273.      * Get and save vRefNum of boot drive
  274.      */
  275.     ZERO(pb);
  276.     pb.ioVRefNum = BootDrive;
  277.     if (PBGetWDInfo (&pb, FALSE) != 0)
  278.         goto exit;
  279.     BootVRefNum = pb.ioWDVRefNum;
  280.     /*
  281.      * Load our DLOG resource, extract the bounding rect, and then
  282.      * purge the resource, since the DLOG exists only to make building
  283.      * the dialog via ResEdit, et al easier.
  284.      */
  285.     h = GetResource ('DLOG', OUR_ID);
  286.     if (h == 0 || ResError())
  287.         goto exit;
  288.     Our_rect = (*(DialogTHndl)h)->boundsRect;
  289.     ReleaseResource (h);
  290.     /*
  291.      * Get our DITL and save its pointer
  292.      */
  293.     h = GetResource ('DITL', OUR_ID);
  294.     if (h == 0 || ResError())
  295.         goto exit;
  296.     Our_DITL_hdl = h;
  297.     /*
  298.      * Allocate nonrelocatable block on system heap for trap code
  299.      */
  300.     len = SizeResource(self);
  301.     asm {
  302.         move.l        len,d0
  303.         NewPtr        SYS
  304.         move.l        a0,p
  305.     }
  306.     if (p == NULL)
  307.         goto exit;
  308.     /*
  309.      * Save original trap address
  310.      */
  311.     Orig_trap = GetTrapAddress (OUR_TRAP_NO);
  312.  
  313.     DetachResource (h);
  314.     /*
  315.      * copy the trap routines to the block
  316.      */
  317.     BlockMove (*self, p, len);
  318.     /*
  319.      * Now that everything is set correctly, set the new code as the
  320.      * trap handler
  321.      */
  322.     addr = (long) (p + (((Ptr)addr - *self) & 0xffff));
  323.     SetTrapAddress (addr, OUR_TRAP_NO);
  324.  
  325. exit:
  326.     HUnlock (self);
  327. }